package main

import (
	"fmt"
	"net"
	"reflect"
)

func closeResource(o interface{}) {
	rType := reflect.TypeOf(o)
	if rType.Kind() != reflect.Pointer {
		fmt.Println("输入类型不可关闭 1")
	}
	rType = rType.Elem()
	if rType.Kind() != reflect.Interface {
		fmt.Println("输入类型不可关闭 2")
		return
	}
	rValue := reflect.ValueOf(o)
	closeMethod := rValue.Elem().MethodByName("Close")
	if closeMethod.IsZero() {
		fmt.Println("未发现Close方法")
		return
	}
	closeResult := closeMethod.Call(nil)
	if closeResult[0].IsNil() {
		fmt.Println(rType.Name(), "关闭成功")
	} else {
		err := closeResult[0].Interface()
		fmt.Println("关闭失败", err)
	}
}

func process(conn net.Conn) {
	for {
		buffer := make([]byte, 1024)
		n, err := conn.Read(buffer)
		if err != nil {
			fmt.Println("读取数据失败，", err)
			return
		}
		msg := string(buffer[:n])
		fmt.Println("来自客户端", conn.RemoteAddr().String(), "的消息 ： ", string(buffer[:n]))
		//双倍返回给客户端
		_, err = conn.Write([]byte("返还给你" + msg))
		if err != nil {
			fmt.Println("给客户端回消息失败", err)
			continue
		}
	}
}

func main() {
	listen, err := net.Listen("tcp", "127.0.0.1:8888")
	if err != nil {
		fmt.Println("监听失败")
		return
	}
	defer closeResource(&listen)

	for {
		fmt.Println("等待客户端链接")
		conn, err := listen.Accept()
		if err != nil {
			fmt.Println("客户端链接失败")
		} else {
			fmt.Println("客户端链接成功，", conn.RemoteAddr().String())
			go process(conn)
		}
	}
}
